<!-- src/views/admin/Dashboard.vue -->
<template>
  <div class="dashboard-page">
    <!-- 1. 顶部数据统计卡片：5 个小卡片 -->
    <el-row :gutter="20" class="stats-row">
      <el-col
        :xs="24"
        :sm="12"
        :md="6"
        :lg="4.8"
        v-for="(stat, index) in stats"
        :key="stat.label"
      >
        <transition name="slide-up" :style="{ '--delay': `${index * 0.1}s` }">
          <el-card class="stat-card" shadow="hover" v-loading="loading.stats">
            <div class="stat-icon" :style="{ backgroundColor: stat.color }">
              <el-icon :size="32">
                <component :is="stat.icon" />
              </el-icon>
            </div>
            <div class="stat-content">
              <div class="stat-value">{{ stat.value }}</div>
              <div class="stat-label">{{ stat.label }}</div>
            </div>
            <div class="stat-trend" v-if="stat.trend !== undefined">
              <span :class="['trend-value', stat.trend > 0 ? 'up' : 'down']">
                {{ stat.trend > 0 ? "+" : "" }}{{ stat.trend }}%
              </span>
              <el-icon :size="14">
                <component :is="markRaw(stat.trend > 0 ? ArrowUp : ArrowDown)" />
              </el-icon>
            </div>
          </el-card>
        </transition>
      </el-col>
    </el-row>

    <!-- 2. 中部图表区域 -->
    <el-row :gutter="20" class="chart-row">
      <el-col :xs="24" :md="15">
        <el-card
          shadow="hover"
          class="chart-card"
          v-loading="loading.salesTrend"
        >
          <div class="chart-card-header">
            <span class="title">销售趋势</span>
            <div class="header-actions">
              <el-radio-group
                v-model="timeRange"
                size="small"
                @change="handleTimeRangeChange"
              >
                <el-radio-button value="week">最近7天</el-radio-button>
                <el-radio-button value="month">本月</el-radio-button>
                <el-radio-button value="year">全年</el-radio-button>
              </el-radio-group>
            </div>
          </div>
          <div class="chart-container">
            <div 
              id="sales-trend-chart" 
              class="echarts-container"
              v-show="salesTrendData.length > 0"
            ></div>
            <div class="chart-placeholder" v-if="!salesTrendData.length">
              暂无销售数据
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :md="9">
        <el-card
          shadow="hover"
          class="chart-card"
          v-loading="loading.categorySales"
        >
          <div class="chart-card-header">
            <span class="title">销售分类占比</span>
          </div>
          <div class="chart-container">
            <div 
              id="category-sales-chart" 
              class="echarts-container"
              v-show="categorySalesData.length > 0"
            ></div>
            <div class="chart-placeholder" v-if="!categorySalesData.length">
              暂无分类数据
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 3. 底部最新订单表格 -->
    <el-card shadow="hover" class="table-card" v-loading="loading.recentOrders">
      <div class="table-card-header">
        <span class="title">最新订单</span>
        <el-button type="primary" link @click="goToOrdersList"
          >查看全部</el-button
        >
      </div>
      <el-table 
        :data="recentOrders" 
        border 
        stripe 
        style="width: 100%"
        :header-cell-style="{
          background: '#f5f7fa',
          color: '#606266',
          fontWeight: 600,
        }"
        empty-text="暂无订单数据"
        @wheel.passive
      >
        <el-table-column
          align="center"
          prop="orderNo"
          label="订单号"
          width="180"
        />
        <el-table-column
          align="center"
          prop="customerName"
          label="客户"
          width="150"
        />
        <el-table-column
          align="center"
          prop="totalAmount"
          label="金额 (¥)"
          width="120"
        >
          <template #default="{ row }">
            <span class="amount">¥{{ formatPrice(row.totalAmount) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          prop="statusText"
          label="状态"
          width="120"
        >
          <template #default="{ row }">
            <el-tag 
              :type="statusTagType(row.status)"
              effect="light"
              class="status-tag"
            >
              {{ row.statusText }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="下单时间" />
        <el-table-column label="操作" width="120" align="center">
          <template #default="{ row }">
            <el-button type="primary" link @click="goToOrderDetail(row.id)">
              查看
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 4. 热门商品 -->
    <el-card shadow="hover" class="table-card" v-loading="loading.hotProducts">
      <div class="table-card-header">
        <span class="title">热门商品</span>
        <el-button type="primary" link @click="goToProductsList"
          >查看全部</el-button
        >
      </div>
      <el-table 
        :data="hotProducts" 
        border 
        stripe 
        style="width: 100%"
        :header-cell-style="{
          background: '#f5f7fa',
          color: '#606266',
          fontWeight: 600,
        }"
        empty-text="暂无商品数据"
        @wheel.passive
      >
        <el-table-column align="center" label="商品图片" width="100">
          <template #default="{ row }">
            <el-image 
              :src="row.image" 
              fit="cover"
              style="width: 50px; height: 50px; border-radius: 4px"
              :preview-src-list="[row.image]"
              :preview-teleported="true"
              :initial-index="0"
              :preview-options="{ 
                maskClosable: true,
                loop: false,
                closeOnPressEscape: true,
                zoomRate: 1.2
              }"
            >
              <template #error>
                <div class="image-placeholder">
                  <el-icon><Picture /></el-icon>
                </div>
              </template>
            </el-image>
          </template>
        </el-table-column>
        <el-table-column prop="name" label="商品名称" />
        <el-table-column align="center" prop="price" label="价格" width="120">
          <template #default="{ row }">
            <span class="amount">¥{{ formatPrice(row.price) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          prop="stockCount"
          label="库存"
          width="120"
        />
        <el-table-column
          align="center"
          prop="salesCount"
          label="销量"
          width="120"
        />
        <el-table-column label="操作" width="120" align="center">
          <template #default="{ row }">
            <el-button type="primary" link @click="goToProductDetail(row.id)">
              查看
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
  </div>
</template>
  
<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick, markRaw, shallowRef } from "vue";
import { useRouter } from "vue-router";
import { 
  getDashboardStats, 
  getSalesTrend,
  getCategorySales,
  getRecentOrders,
  getHotProducts
} from "@/api/dashboard";
import * as echarts from 'echarts/core';
import { 
  LineChart,
  PieChart
} from 'echarts/charts';
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { 
  Tickets, 
  User, 
  Money, 
  Discount, 
  ShoppingCart, 
  ArrowUp, 
  ArrowDown, 
  More, 
  Picture
} from '@element-plus/icons-vue';
import { ElMessage } from "element-plus";

// 注册ECharts组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  LineChart,
  PieChart,
  CanvasRenderer
]);

const router = useRouter();

// 使用shallowRef来存储图表实例，避免将整个图表对象变成响应式
const salesTrendChart = shallowRef(null);
const categorySalesChart = shallowRef(null);

// 加载状态
const loading = ref({
  stats: true,
  salesTrend: true,
  categorySales: true,
  recentOrders: true,
  hotProducts: true,
});

// 1. 统计卡片的数据
const stats = ref([
  {
    label: "今日订单",
    value: "0",
    icon: markRaw(ShoppingCart),
    color: "#f56c6c",
    trend: 0,
  },
  {
    label: "总用户数",
    value: "0",
    icon: markRaw(User),
    color: "#409EFF",
    trend: 0,
  },
  {
    label: "总收入",
    value: "¥ 0.00",
    icon: markRaw(Money),
    color: "#67C23A",
    trend: 0,
  },
  {
    label: "纯利润",
    value: "¥ 0.00",
    icon: markRaw(Money),
    color: "#E6A23C",
    trend: 0,
  },
  {
    label: "优惠券使用",
    value: "0",
    icon: markRaw(Discount),
    color: "#E6A23C",
    trend: 0,
  },
]);

// 时间范围选择
const timeRange = ref("week");

// 2. 销售趋势数据
const salesTrendData = ref([]);

// 3. 分类销售数据
const categorySalesData = ref([]);

// 4. 最新订单表格数据
const recentOrders = ref([]);

// 5. 热门商品数据
const hotProducts = ref([]);

// 自动刷新定时器
let refreshTimer = null;

// 格式化价格
const formatPrice = (price) => {
  if (price === undefined || price === null) return "0.00";
  return parseFloat(price).toFixed(2);
};

// 将不同状态映射成 Tag 类型
function statusTagType(status) {
  // 如果是数字类型的状态码
  if (!isNaN(status)) {
    const statusCode = parseInt(status);
    switch (statusCode) {
      case 0:
        return "info"; // 待付款
      case 1:
        return "warning"; // 待发货
      case 2:
        return "warning"; // 备货中
      case 3:
        return "primary"; // 配送中
      case 4:
        return "success"; // 已完成
      case 5:
        return "danger"; // 已取消
      case 6:
        return "info"; // 待确认收货
      case 7:
        return "warning"; // 待自提
      case 8:
        return "danger"; // 已退款
      default:
        return "";
    }
  }
  
  // 兼容旧的字符串状态
  switch (status) {
    case "completed":
      return "success";
    case "paid":
    case "ready_for_pickup":
      return "warning";
    case "shipping":
      return "primary";
    case "delivered":
      return "info";
    case "pending":
      return "info";
    case "refunding":
    case "refunded":
    case "cancelled":
      return "danger";
    default:
      return "";
  }
}

// 窗口大小调整处理函数
const handleResize = () => {
  if (salesTrendChart.value) {
    try {
      salesTrendChart.value.resize();
    } catch (e) {
      console.error('调整销售趋势图表大小失败:', e);
    }
  }
  
  if (categorySalesChart.value) {
    try {
      categorySalesChart.value.resize();
    } catch (e) {
      console.error('调整分类销售图表大小失败:', e);
    }
  }
};

// 获取统计数据
const fetchStats = async () => {
  loading.value.stats = true;
  try {
    const res = await getDashboardStats();
    if (res.code === 200) {
      const data = res.data;

      // 更新统计卡片数据
      stats.value[0].value = data.todayOrderCount;
      stats.value[0].trend = data.orderCountTrend;
      
      stats.value[1].value = data.totalUserCount;
      stats.value[1].trend = data.userCountTrend;
      
      stats.value[2].value = `¥ ${formatPrice(data.totalRevenue)}`;
      stats.value[2].trend = data.revenueTrend;

      stats.value[3].value = `¥ ${formatPrice(data.netProfit)}`;
      stats.value[3].trend = 0; // 这里可以根据需求计算趋势
      
      stats.value[4].value = data.couponUsageCount;
      stats.value[4].trend = data.couponUsageTrend;
    }
  } catch (error) {
    console.error("获取统计数据失败:", error);
    ElMessage.error("获取统计数据失败");
  } finally {
    loading.value.stats = false;
  }
};

// 时间范围选择变化时，同时更新两个图表
const handleTimeRangeChange = (value) => {
  timeRange.value = value;
  fetchSalesTrend();
  fetchCategorySales();
}

// 获取销售趋势数据
const fetchSalesTrend = async () => {
  loading.value.salesTrend = true;
  salesTrendData.value = []; // 清空现有数据
  
  try {
    const res = await getSalesTrend(timeRange.value);
    if (res.code === 200) {
      // 确保数据不为null，否则使用空数组
      salesTrendData.value = res.data || [];
      
      // 只有在有数据且DOM元素存在时才渲染图表
      if (document.getElementById('sales-trend-chart')) {
        await renderSalesTrendChart();
      }
    } else {
      console.error("获取销售趋势数据失败:", res.msg);
    }
  } catch (error) {
    console.error("获取销售趋势数据失败:", error);
    ElMessage.error("获取销售趋势数据失败");
  } finally {
    loading.value.salesTrend = false;
  }
};

// 获取分类销售数据
const fetchCategorySales = async () => {
  loading.value.categorySales = true;
  categorySalesData.value = []; // 清空现有数据
  
  try {
    const res = await getCategorySales(timeRange.value);
    if (res.code === 200) {
      // 确保数据不为null，否则使用空数组
      categorySalesData.value = res.data || [];
      
      // 只有在有数据且DOM元素存在时才渲染图表
      if (document.getElementById('category-sales-chart')) {
        await renderCategorySalesChart();
      }
    } else {
      console.error("获取分类销售数据失败:", res.msg);
    }
  } catch (error) {
    console.error("获取分类销售数据失败:", error);
    ElMessage.error("获取分类销售数据失败");
  } finally {
    loading.value.categorySales = false;
  }
};

// 获取最近订单数据
const fetchRecentOrders = async () => {
  loading.value.recentOrders = true;
  try {
    const res = await getRecentOrders(5);
    if (res.code === 200) {
      recentOrders.value = res.data || [];
    }
  } catch (error) {
    console.error("获取最近订单数据失败:", error);
    ElMessage.error("获取最近订单数据失败");
  } finally {
    loading.value.recentOrders = false;
  }
};

// 获取热门商品数据
const fetchHotProducts = async () => {
  loading.value.hotProducts = true;
  try {
    const res = await getHotProducts(5);
    if (res.code === 200) {
      hotProducts.value = res.data || [];
    }
  } catch (error) {
    console.error("获取热门商品数据失败:", error);
    ElMessage.error("获取热门商品数据失败");
  } finally {
    loading.value.hotProducts = false;
  }
};

// 渲染销售趋势图表
const renderSalesTrendChart = async () => {
  try {
    await nextTick();
    const chartDom = document.getElementById('sales-trend-chart');
    if (!chartDom) {
      console.error('销售趋势图表DOM元素不存在');
      return;
    }
    
    // 销毁旧的实例 - 更安全的检查
    if (salesTrendChart.value) {
      try {
        salesTrendChart.value.dispose();
      } catch (e) {
        console.error('销毁销售趋势图表失败:', e);
      }
    }
    
    // 创建新的图表实例
    salesTrendChart.value = echarts.init(chartDom, null, {
      renderer: 'canvas',
      useDirtyRect: true,
      // 添加事件配置，使用passive模式解决滚动警告
      eventOptions: { passive: true }
    });
    
    const data = salesTrendData.value || [];
    const xData = data.map(item => item.date);
    const yData = data.map(item => item.amount);
    
    // 使用markRaw处理整个配置对象
    const option = markRaw({
      tooltip: {
        trigger: 'axis',
        formatter: function(params) {
          const item = params[0];
          return `${item.name}<br/>${item.marker}销售额: ¥${item.value.toFixed(2)}`;
        }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: xData,
        axisLine: {
          lineStyle: {
            color: '#dcdfe6'
          }
        },
        axisLabel: {
          color: '#606266'
        }
      },
      yAxis: {
        type: 'value',
        axisLine: {
          show: false
        },
        axisTick: {
          show: false
        },
        splitLine: {
          lineStyle: {
            color: '#ebeef5'
          }
        },
        axisLabel: {
          color: '#606266',
          formatter: function(value) {
            return '¥' + value;
          }
        }
      },
      series: [
        {
          name: '销售额',
          type: 'line',
          smooth: true,
          symbol: 'circle',
          symbolSize: 6,
          itemStyle: {
            color: '#409EFF'
          },
          lineStyle: {
            width: 3,
            color: '#409EFF'
          },
          areaStyle: {
            color: markRaw(new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: 'rgba(64, 158, 255, 0.3)'
              },
              {
                offset: 1,
                color: 'rgba(64, 158, 255, 0.1)'
              }
            ]))
          },
          data: yData
        }
      ]
    });
    
    // 安全的设置选项
    if (salesTrendChart.value) {
      salesTrendChart.value.setOption(option);
    }
  } catch (error) {
    console.error('渲染销售趋势图表失败:', error);
  }
};

// 渲染分类销售图表
const renderCategorySalesChart = async () => {
  try {
    await nextTick();
    const chartDom = document.getElementById('category-sales-chart');
    if (!chartDom) {
      console.error('分类销售图表DOM元素不存在');
      return;
    }
    
    // 销毁旧的实例 - 更安全的检查
    if (categorySalesChart.value) {
      try {
        categorySalesChart.value.dispose();
      } catch (e) {
        console.error('销毁分类销售图表失败:', e);
      }
    }
    
    // 创建新的图表实例
    categorySalesChart.value = echarts.init(chartDom, null, {
      renderer: 'canvas',
      useDirtyRect: true,
      // 添加事件配置，使用passive模式解决滚动警告
      eventOptions: { passive: true }
    });
    
    const data = categorySalesData.value || [];
    
    // 创建数据系列
    const seriesData = data.map(item => ({
      name: item.categoryName,
      value: item.salesAmount
    }));
    
    const option = markRaw({
      tooltip: {
        trigger: 'item',
        formatter: function(params) {
          return `${params.name}<br/>${params.marker}销售额: ¥${params.value.toFixed(2)}<br/>占比: ${params.percent}%`;
        }
      },
      legend: {
        orient: 'vertical',
        right: 10,
        top: 'center',
        itemWidth: 10,
        itemHeight: 10,
        textStyle: {
          color: '#606266'
        }
      },
      series: [
        {
          name: '分类销售',
          type: 'pie',
          radius: ['40%', '70%'],
          center: ['40%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: false,
          },
          emphasis: {
            label: {
              show: true,
              fontSize: '12',
              fontWeight: 'bold'
            }
          },
          labelLine: {
            show: false
          },
          data: seriesData.length > 0 ? seriesData : [{name: '暂无数据', value: 1}]
        }
      ],
      color: [
        '#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399',
        '#36BFFF', '#DCDFE6', '#67c587', '#f7c770', '#f78989'
      ]
    });
    
    // 安全的设置选项
    if (categorySalesChart.value) {
      categorySalesChart.value.setOption(option);
    }
  } catch (error) {
    console.error('渲染分类销售图表失败:', error);
  }
};

// 导航到订单列表
const goToOrdersList = () => {
  router.push("/home/orders");
};

// 导航到订单详情
const goToOrderDetail = (id) => {
  router.push({
    path: `/home/orders/detail/${id}`,
    query: { source: 'dashboard' }
  });
};

// 导航到商品列表
const goToProductsList = () => {
  router.push("/home/products");
};

// 导航到商品详情
const goToProductDetail = (id) => {
  router.push({
    path: `/home/products/${id}`,
    query: { source: 'dashboard' }
  });
};

// 初始化数据
const initDashboard = async () => {
  try {
    // 先获取基础统计数据
    await fetchStats();
    
    // 再获取并渲染图表数据
    await Promise.all([
      fetchSalesTrend(),
      fetchCategorySales()
    ]);
    
    // 最后获取表格数据
    await Promise.all([
      fetchRecentOrders(),
      fetchHotProducts()
    ]);
    
  } catch (error) {
    console.error('初始化仪表盘失败:', error);
  }
};

// 生命周期钩子
onMounted(() => {
  nextTick(() => {
    initDashboard();
  });
  
  // 添加窗口大小变化监听，设置passive: true以避免滚动警告
  window.addEventListener('resize', handleResize, { passive: true });
  
  // 设置自动刷新（每5分钟刷新一次）
  refreshTimer = setInterval(() => {
    fetchStats();
    fetchRecentOrders();
  }, 5 * 60 * 1000);
});

// 组件卸载时清除定时器和图表实例
onBeforeUnmount(() => {
  // 移除事件监听器，确保使用相同的参数
  window.removeEventListener('resize', handleResize, { passive: true });
  
  // 清除刷新定时器
  if (refreshTimer) {
    clearInterval(refreshTimer);
    refreshTimer = null;
  }
  
  // 销毁图表实例
  if (salesTrendChart.value) {
    try {
      salesTrendChart.value.dispose();
    } catch (e) {
      console.error('销毁销售趋势图表失败:', e);
    }
    salesTrendChart.value = null;
  }
  
  if (categorySalesChart.value) {
    try {
      categorySalesChart.value.dispose();
    } catch (e) {
      console.error('销毁分类销售图表失败:', e);
    }
    categorySalesChart.value = null;
  }
});
</script>
  
<style scoped>
.dashboard-page {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 20px;
  background: #f5f7fa;
  min-height: 100vh;
}

/* 1. 统计卡片行 */
.stats-row {
  margin-bottom: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.stat-card {
  display: flex;
  align-items: center;
  padding: 20px;
  border-radius: 12px;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
  height: 100%;
  margin-bottom: 20px;
}

.stat-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
}

.stat-icon {
  width: 60px;
  height: 60px;
  border-radius: 12px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: 16px;
  color: #fff;
  transition: all 0.3s ease;
}

.stat-card:hover .stat-icon {
  transform: scale(1.1);
}

.stat-content {
  flex: 1;
}

.stat-value {
  font-size: 24px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 4px;
}

.stat-label {
  font-size: 14px;
  color: #909399;
}

.stat-trend {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
}

.trend-value.up {
  color: #67c23a;
}

.trend-value.down {
  color: #f56c6c;
}

/* 2. 图表区域 */
.chart-row {
  margin-bottom: 0;
  display: flex;
  flex-wrap: wrap;
}

.chart-card {
  border-radius: 12px;
  transition: all 0.3s ease;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.chart-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
}

.chart-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 0 16px;
  padding-top: 16px;
}

.chart-card-header .title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.chart-container {
  height: 350px;
  flex-grow: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  position: relative;
}

.echarts-container {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

.chart-placeholder {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #909399;
  background: #ffffff;
  border: 1px dashed #dcdfe6;
  border-radius: 8px;
  font-size: 14px;
}

/* 3. 最新订单表格 */
.table-card {
  border-radius: 12px;
  transition: all 0.3s ease;
}

.table-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
}

.table-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.table-card-header .title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.amount {
  font-family: "Monaco", monospace;
  font-weight: 500;
  color: #67c23a;
}

.status-tag {
  padding: 4px 8px;
  border-radius: 4px;
}

.image-placeholder {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 50px;
  height: 50px;
  background-color: #f5f7fa;
  border-radius: 4px;
  color: #909399;
}

/* 动画效果 */
.slide-up-enter-active {
  transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  transition-delay: var(--delay);
}

.slide-up-enter-from {
  opacity: 0;
  transform: translateY(20px);
}

/* 响应式调整 */
@media screen and (max-width: 768px) {
  .dashboard-page {
    padding: 16px;
    gap: 16px;
  }

  .stat-card {
    padding: 16px;
    margin-bottom: 16px;
  }

  .stat-icon {
    width: 48px;
    height: 48px;
    margin-right: 12px;
  }

  .stat-value {
    font-size: 20px;
  }

  .chart-container {
    height: 300px;  
  }
}

@media screen and (min-width: 769px) and (max-width: 992px) {
  .chart-row > div {
    margin-bottom: 20px;
  }
  
  .stats-row > div {
    width: 50%;
    flex: 0 0 50%;
    max-width: 50%;
  }
}

@media screen and (min-width: 993px) and (max-width: 1200px) {
  .stats-row > div {
    width: 20%;
    flex: 0 0 20%;
    max-width: 20%;
  }
  
  .chart-row {
    display: flex;
  }
  
  .chart-row > div {
    display: flex;
  }
  
  .chart-card {
    width: 100%;
  }
}

@media screen and (min-width: 1201px) {
  .stats-row > div {
    width: 20%;
    flex: 0 0 20%;
    max-width: 20%;
  }
  
  .chart-row {
    display: flex;
  }
  
  .chart-row > div {
    display: flex;
  }
  
  .chart-card {
    width: 100%;
  }
}
</style>
  
  